package tests;

import static org.junit.Assert.*;

import java.util.HashMap;
import java.util.LinkedList;

import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;

import recipie.core.Ingredient;
import recipie.core.MesureUnit;
import recipie.core.Recipe;
import recipie.core.RecipeCollection;
import database.Repository;

public class DatabaseRecipeTest 
{
  private static Recipe recipe_1 = null;
  private static Recipe recipe_2 = null;
  private static Recipe sub_recipe_1 = null;
  private static Recipe sub_recipe_2 = null;
  private static LinkedList<String> recipe1_ingredients = null;
  private static LinkedList<String> recipe2_subrecipes= null;
  private static Ingredient ingredient_1 = null;
  private static Ingredient ingredient_2 = null;
  private static HashMap<String,Integer> recipe_1_quantities = null;
	
	@BeforeClass
	public static void setUp() 
	{
	  ingredient_1 = new Ingredient("ing_1", MesureUnit.g);
	  ingredient_2 = new Ingredient("ing_2", MesureUnit.ml);
	  
	  recipe1_ingredients = new LinkedList<String>();
	  recipe2_subrecipes = new LinkedList<String>();
	  
	  recipe1_ingredients.add("ing_1");
	  recipe1_ingredients.add("ing_2");
	  
	  recipe2_subrecipes.add("sub_rec_1");
	  recipe2_subrecipes.add("sub_rec_2");
	  
	  recipe_1_quantities = new HashMap<String,Integer>();
	  recipe_1_quantities.put(recipe1_ingredients.get(0), 2);
	  recipe_1_quantities.put(recipe1_ingredients.get(1), 5);
	  
	  recipe_1 = new Recipe("rec_1", 3, false, 2, "source", recipe1_ingredients, null, null, recipe_1_quantities);
	  sub_recipe_1 = new Recipe("sub_rec_1", 3, false, 2, "source", null, null, null, null);
	  sub_recipe_2 = new Recipe("sub_rec_2", 3, false, 2, "source", null, null, null, null);
	  recipe_2 = new Recipe("rec_2", 3, false, 2, "source", recipe1_ingredients, recipe2_subrecipes, null, null);
	  
	  Repository.insertIngredient(ingredient_1);
	  Repository.insertIngredient(ingredient_2);
	}
	
	@Test
	public void insertRecipeWithNoSubRecipes() 
	{
	  Repository.insertRecipe(recipe_1);
	  RecipeCollection recipes = Repository.loadRecipes();
	  assertTrue(recipes.getRecipes().get("rec_1") != null);
	}
	
	@Test
	public void insertRecipeWithSubRecipes() 
	{
	  Repository.insertRecipe(sub_recipe_1);
	  Repository.insertRecipe(sub_recipe_2);
	  Repository.insertRecipe(recipe_2);
	  RecipeCollection recipes = Repository.loadRecipes();
	  assertTrue(recipes.getRecipes().get("rec_2") != null && 
			     recipes.getRecipes().get("rec_2").getSubRecipes().get(0).equals("sub_rec_1") &&
			     recipes.getRecipes().get("rec_2").getSubRecipes().get(1).equals("sub_rec_2"));
	}
	
	@Test
	public void checkIngredientsAndQuantitiesConsistency() 
	{
	  RecipeCollection recipes = Repository.loadRecipes();
	  assertTrue(recipes.getRecipes().get("rec_1").getIngredients().get(0).equals("ing_1"));
	  assertTrue(recipes.getRecipes().get("rec_1").getIngredients().get(1).equals("ing_2"));
	  assertTrue(recipes.getRecipes().get("rec_1").getIngredientsQuantities().get("ing_1") == 2);
	  assertTrue(recipes.getRecipes().get("rec_1").getIngredientsQuantities().get("ing_2") == 5);
	}
	
	@Test
	public void recipeExample() 
	{
	  Ingredient ingredient_1 = new Ingredient("ingredient_1", MesureUnit.g);
	  Ingredient ingredient_2 = new Ingredient("ingredient_2", MesureUnit.kg);
	  Repository.insertIngredient(ingredient_1);
	  Repository.insertIngredient(ingredient_2);
	  
	  LinkedList<String> recipe_ingredients = new LinkedList<String>();
	  recipe_ingredients.add("ingredient_1");
	  recipe_ingredients.add("ingredient_2");
	  
	  HashMap<String,Integer> recipe_1_quantities = new HashMap<String,Integer>();
	  recipe_1_quantities.put("ingredient_1", 3);
	  recipe_1_quantities.put("ingredient_2", 7);
	  
	  Recipe recipe = new Recipe("recipe", 3, false, 2, "source", recipe_ingredients, null, null, recipe_1_quantities);	
	  //Before inserting a recipe, his ingredients or his subrecipes must already be present into the database
	  Repository.insertRecipe(recipe);
	  
	  RecipeCollection recipes = Repository.loadRecipes();
	  assertTrue(recipes.getRecipes().get("recipe").getIngredients().get(0).equals("ingredient_1"));
	  assertTrue(recipes.getRecipes().get("recipe").getIngredients().get(1).equals("ingredient_2"));
	  assertTrue(recipes.getRecipes().get("recipe").getIngredientsQuantities().get("ingredient_1") == 3);
	  assertTrue(recipes.getRecipes().get("recipe").getIngredientsQuantities().get("ingredient_2") == 7);
	  
	  //To clean up the database
	  Repository.deleteIngredient(ingredient_1);
	  Repository.deleteIngredient(ingredient_2);
	  Repository.deleteRecipe(recipe);
	}
	
    @AfterClass
	public static void cleanUp() 
	{
	  Repository.deleteIngredient(ingredient_1);
	  Repository.deleteIngredient(ingredient_2);
	  Repository.deleteRecipe(recipe_1);
	  Repository.deleteRecipe(recipe_2);
	  Repository.deleteRecipe(sub_recipe_1);
	  Repository.deleteRecipe(sub_recipe_2);
	}

}
